
;컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴
;    DMA_READ
;       Set up DMA for a 16-bit adapter to memory transfer, using 
;       DMA channel 5 which is activated by the hardware DMA 
;       request 5 (DRQ 5) line.
;
;        Notes: 1) operation for AT+ systems only (not for PC/XT)
;               2) ds:si must be word aligned, with si bit 0 = 0
;               3) ds:si + dx must not cross a 128KB boundary
;
;       Called with:    ds:si = memory buffer to read into
;                       dx    = count, number of WORDS (not bytes)

DMA_read        proc    near
        cli
        mov     al, 00000101b      ; set channel 5 mask bit
        out     0D4h, al           ;  to disable DMA
        IODELAY
        out     0D8h, al           ; clear byte flip/flop
                                   ;  (al value unimportant)
        IODELAY
        mov     al, 01001001h      ; mode byte: single mode, 
                                   ;  increment, no autoinit, 
                                   ;  read, channel 5
        out     0D6h, al           
        IODELAY
                                   ; Convert es:si to 32-bit 
                                   ;  linear and output to DMA-2
        mov     ax, es          
        mov     cl, 4
        rol     ax, cl   
        push    ax
        and     al, 0Fh            ; al = address bits a16 to a23
        out     08Bh, al           ; load channel 5 page register
        IODELAY
        pop     ax
        and     ax, 0FFF0h         ; segment * 16
        add     ax, si             ; ax = address bits a0 to a15
        out     0C4h, al           ; output low address byte
        IODELAY
        mov     al, ah
        out     0C4h, al           ; output high address byte
        IODELAY
                                   ; Send Count of Words to DMA-2

        mov     ax, dx             ; get count
        dec     dx                 ; adjust, since DMA count 
                                   ;   is 1 more
        out     0C6h, al           ; output low count byte
        IODELAY
        mov     al, ah
        out     0C6h, al           ; output high count byte
        IODELAY
        mov     al, 00000001b      ; clear channel 5 mask bit
        out     0D4h, al           ;  to enable DMA
        IODELAY
                                   ; Now it's up to hardware!
        sti
        ret
DMA_read        endp

